package mgodb

import (
	"github.com/facebookgo/inject"
	"github.com/globalsign/mgo"
	"github.com/globalsign/mgo/bson"
	"github.com/pkg/errors"
	"jgt-oper/src/model"
	"jgt-oper/src/schema"
	"jgt-oper/src/service/mongo"
)

// cPublicResource 公共资源管理数据表
const cResourceReserved = "oper_resource_reserved"

// ResourceReserved 资源预定管理管理
type ResourceReserved struct {
	DB *mongo.DB
}

// Init 初始化
func (a *ResourceReserved) Init(g *inject.Graph, db *mongo.DB) {
	a.DB = db

	// 初始化mongo索引
	a.DB.C(cResourceReserved, func(c *mgo.Collection) error {
		c.EnsureIndex(mgo.Index{
			Key:    []string{"record_id", "deleted"},
			Unique: true,
		})
		c.EnsureIndexKey("_id")
		return nil
	})

	var val model.IResourceReserved = a
	g.Provide(&inject.Object{Value: val, Name: "IResourceReserved"})
}

// Create 创建条目
func (a *ResourceReserved) Create(item *schema.ResourceReserved) error {
	err := a.DB.C(cResourceReserved, func(c *mgo.Collection) error {
		id, err := a.DB.IncrID(cResourceReserved)
		if err != nil {
			return err
		}
		item.ID = id
		return c.Insert(item)
	})
	if err != nil {
		return errors.Wrapf(err, "创建数据发生错误")
	}
	return nil
}

// Get 查询条目
func (a *ResourceReserved) Get(recordID string) (*schema.ResourceReserved, error) {
	item := new(schema.ResourceReserved)
	err := a.DB.C(cResourceReserved, func(c *mgo.Collection) error {
		return c.Find(bson.M{"record_id": recordID}).One(item)
	})
	if err != nil {
		if err == mgo.ErrNotFound {
			return nil, nil
		}
		return nil, errors.Wrapf(err, "精确查询数据发生错误")
	}
	return item, nil
}

// QueryItems 根据指定资源id、指定日期查询预约情况
func (a *ResourceReserved) QueryItems(resourceID, date string) ([]*schema.ResourceReserved, error) {
	query := bson.M{
		"deleted":     0,
		"resource_id": resourceID,
		"status":      1,
		"hours_reserved." + date: bson.M{
			"$exists": true,
		},
	}
	var items []*schema.ResourceReserved
	var err error
	err = a.DB.C(cResourceReserved, func(c *mgo.Collection) error {
		return c.Find(query).All(&items)
	})
	if err != nil {
		return nil, err
	}
	return items, nil
}

func (a *ResourceReserved) Update(recordID string, info map[string]interface{}) error {
	err := a.DB.C(cResourceReserved, func(c *mgo.Collection) error {
		return c.Update(bson.M{"record_id": recordID, "deleted": 0}, bson.M{"$set": info})
	})
	if err != nil {
		return errors.Wrapf(err, "更新数据发生错误")
	}
	return nil
}

func (a *ResourceReserved) QueryReservedPage(params *schema.ResourceReservedQParams) (int, []*schema.ResourceReserved, error) {
	query := bson.M{
		"deleted": 0,
	}
	if params.UserID != "" {
		query["creator"] = params.UserID
	}
	if params.ApplicationStatus == 0 {
		query["application_status"] = 0
	}
	if params.ApplicationStatus == 1 {
		query["application_status"] = bson.M{
			"$in": []int{1, 2, 3},
		}
	}
	var total int
	var items []*schema.ResourceReserved
	var err error
	err = a.DB.C(cResourceReserved, func(c *mgo.Collection) error {
		total, err = c.Find(query).Count()
		if err != nil {
			return err
		}

		return c.Find(query).Sort("-_id").Skip(int((params.PageIndex - 1) * params.PageSize)).Limit(int(params.PageSize)).All(&items)
	})
	if err != nil {
		return 0, nil, errors.Wrapf(err, "查询分页数据发生错误")
	}

	return total, items, nil
}
